# **************************************************************************/
# *********************---------------------------------**********************/
# ********************|    Copyright (c) 2003 - 2023    |*********************/
# ********************|      by VIRE Technologies.        |*********************/
# ********************|       All Rights Reserved           |*********************/
# *********************---------------------------------**********************/
# **************************************************************************/
# 
#  If any question, please write to VIRE Technologies for
#  more information:
# 			Techart Plaza, A16, No.30 XueYuan Road,
# 			Haidian District Beijing 100083,
# 			P.R. China
# 
#  For more, please visit company website: www.vire.cn
# **************************************************************************/
#
# WSF CMake Configuration
#
# This file defines the commands and macros that are used
# to include optional extensions (or modules) in a WSF build.

include(ewxdev_project)

# Adds the optional extension as a CMake option (BUILD_WITH_xxxx) and
# sets global properties that locate and identify extensions
function(add_wsf_optional_project EXTDIR PROJROOT PROJNAME PROJTYPE PROJBUILD)
   set(BUILD_WITH_${PROJNAME} ${PROJBUILD} CACHE BOOL "Build with ${PROJNAME}")
   set_property(GLOBAL PROPERTY WSF_OPTIONAL_PROJECT_NAMES ${PROJNAME} APPEND)
   set_property(GLOBAL PROPERTY WSF_OPTIONAL_PROJECT_TYPES ${PROJTYPE} APPEND)
   set_property(GLOBAL PROPERTY WSF_OPTIONAL_PROJECT_EXTDIRS "${EXTDIR}" APPEND)
   set_property(GLOBAL PROPERTY WSF_OPTIONAL_PROJECT_ROOTS "${PROJROOT}" APPEND)
endfunction()

# Add any optional extensions that have been found to the build
macro(WSF_ADD_EXTENSION EXT_FILE)
   # Initialize variables to be output by extension's configuration
   # The extension name
   set(WSF_EXT_NAME)
   # The extensions add type "lib" for libraries,
   # "exe" is for executables with dependencies
   set(WSF_EXT_TYPE "lib")
   # relative path from extension's cmake to source directory
   set(WSF_EXT_SOURCE_PATH)
   #
   set(WSF_EXT_BUILD TRUE)

   include("${EXT_FILE}")
   if (WSF_EXT_NAME)
      message(STATUS "==Configuring ${WSF_EXT_NAME}...")
      message(STATUS "  WSF_EXT_NAME: ${WSF_EXT_NAME}")
      message(STATUS "  WSF_EXT_TYPE: ${WSF_EXT_TYPE}")
      message(STATUS "  WSF_EXT_BUILD: ${WSF_EXT_BUILD}")

      get_filename_component(EXT_DIR "${EXT_FILE}" PATH)
      message(STATUS "  EXT_DIR: ${EXT_DIR}")
      
      set(PROJROOT "${EXT_DIR}/${WSF_EXT_SOURCE_PATH}")
      message(STATUS "  PROJROOT: ${PROJROOT}")

      add_wsf_optional_project("${EXT_DIR}" "${PROJROOT}" ${WSF_EXT_NAME} ${WSF_EXT_TYPE} ${WSF_EXT_BUILD})
   endif()
endmacro()

ewxdev_absolute_paths(WSF_EXTENSION_FILES ${WSF_EXTENSION_FILES})
foreach(EXT_FILE ${WSF_EXTENSION_FILES})
   WSF_ADD_EXTENSION(${EXT_FILE})
endforeach()

# Configure the build to include optional extensions by creating
# the wsf_extensions.hpp file for the available extensions
get_filename_component(WSF_PATH ${CMAKE_CURRENT_LIST_FILE} PATH)
macro(use_wsf_optional_projects)
   #process_preprocessor_files()
   get_property(WSF_OPTIONAL_PROJECT_NAMES GLOBAL PROPERTY WSF_OPTIONAL_PROJECT_NAMES)
   get_property(WSF_OPTIONAL_PROJECT_TYPES GLOBAL PROPERTY WSF_OPTIONAL_PROJECT_TYPES)
   get_property(WSF_OPTIONAL_PROJECT_ROOTS GLOBAL PROPERTY WSF_OPTIONAL_PROJECT_ROOTS)
   # Write out the wsf_extensions.hpp file
   # using the set of extensions currently enabled
   set(__WSF_EXTENSION_REGISTRATION__ "// WARNING: This code is generated by CMake.  Do not hand-edit.\n")
   if(NOT USE_WSF_OPTIONAL_PROJECTS_CALLED)
      set(USE_WSF_OPTIONAL_PROJECTS_CALLED TRUE)
      set(ROOTDIR ${WSF_OPTIONAL_PROJECTS_ROOT})
      foreach(PROJNAME ${WSF_OPTIONAL_PROJECT_NAMES})
         if(BUILD_WITH_${PROJNAME})
            list(FIND WSF_OPTIONAL_PROJECT_NAMES ${PROJNAME} IDX)
            list(GET WSF_OPTIONAL_PROJECT_TYPES ${IDX} PROJTYPE)
            list(GET WSF_OPTIONAL_PROJECT_ROOTS ${IDX} PROJROOT)
            IF(${PROJTYPE} STREQUAL "lib")
               try_add_subdirectory("${PROJROOT}" "build_${PROJNAME}")
               # Don't do registrations for .exe projects
               IF(TARGET ${PROJNAME})
                  get_target_property(TARGETTYPE ${PROJNAME} TYPE)
                  if(TARGETTYPE STREQUAL "STATIC_LIBRARY" OR TARGETTYPE STREQUAL "SHARED_LIBRARY")
                     set(__WSF_EXTENSION_REGISTRATION__ "${__WSF_EXTENSION_REGISTRATION__}
#if ((!defined(WSF_INCLUDE_EXTENSIONS) && !defined(WSF_EXCLUDE_EXTENSION_${PROJNAME})) || \\
     ( defined(WSF_INCLUDE_EXTENSIONS) &&  defined(WSF_INCLUDE_EXTENSION_${PROJNAME})))
   PrintOptionalExtensionIncluded(\"${PROJNAME}\", listNote);
   WSF_REGISTER_EXTENSION(aApplication, ${PROJNAME});
#endif")
                  ENDIF()
               ENDIF()
            ENDIF()
         ENDIF()
      endforeach()

      foreach(PROJNAME ${WSF_OPTIONAL_PROJECT_NAMES})
         if(BUILD_WITH_${PROJNAME})
            list(FIND WSF_OPTIONAL_PROJECT_NAMES ${PROJNAME} IDX)
            list(GET WSF_OPTIONAL_PROJECT_TYPES ${IDX} PROJTYPE)
            list(GET WSF_OPTIONAL_PROJECT_ROOTS ${IDX} PROJROOT)
            IF(${PROJTYPE} STREQUAL "plugin")
               try_add_subdirectory("${PROJROOT}" "build_${PROJNAME}")
               IF(TARGET ${PROJNAME})
                  get_target_property(TARGETTYPE ${PROJNAME} TYPE)
                  if(TARGETTYPE STREQUAL "STATIC_LIBRARY") # try to add it as a static library.
                     set(__WSF_EXTENSION_REGISTRATION__ "${__WSF_EXTENSION_REGISTRATION__}
#if ((!defined(WSF_INCLUDE_EXTENSIONS) && !defined(WSF_EXCLUDE_EXTENSION_${PROJNAME})) || \\
     ( defined(WSF_INCLUDE_EXTENSIONS) &&  defined(WSF_INCLUDE_EXTENSION_${PROJNAME})))
   PrintOptionalExtensionIncluded(\"${PROJNAME}\", listNote);
   WSF_REGISTER_EXTENSION(aApplication, ${PROJNAME});
#endif")
                  ENDIF()
               ENDIF()
            ENDIF()
         ENDIF()
      endforeach()

      foreach(PROJNAME ${WSF_OPTIONAL_PROJECT_NAMES})
         if(BUILD_WITH_${PROJNAME})
            list(FIND WSF_OPTIONAL_PROJECT_NAMES ${PROJNAME} IDX)
            list(GET WSF_OPTIONAL_PROJECT_TYPES ${IDX} PROJTYPE)
            list(GET WSF_OPTIONAL_PROJECT_ROOTS ${IDX} PROJROOT)
            IF(${PROJTYPE} STREQUAL "exe")
               try_add_subdirectory("${PROJROOT}" "build_${PROJNAME}")
               # Don't do registrations for .exe projects
               IF(TARGET ${PROJNAME})
                  get_target_property(TARGETTYPE ${PROJNAME} TYPE)
                  if(TARGETTYPE STREQUAL "STATIC_LIBRARY" OR TARGETTYPE STREQUAL "SHARED_LIBRARY")
                     set(__WSF_EXTENSION_REGISTRATION__ "${__WSF_EXTENSION_REGISTRATION__}
#if ((!defined(WSF_INCLUDE_EXTENSIONS) && !defined(WSF_EXCLUDE_EXTENSION_${PROJNAME})) || \\
     ( defined(WSF_INCLUDE_EXTENSIONS) &&  defined(WSF_INCLUDE_EXTENSION_${PROJNAME})))
   PrintOptionalExtensionIncluded(\"${PROJNAME}\", listNote);
   WSF_REGISTER_EXTENSION(aApplication, ${PROJNAME});
#endif")
                  ENDIF()
               ENDIF()
            ENDIF()
         ENDIF()
      endforeach()
   endif()
   configure_file("${WSF_PATH}/wsf_extensions.hpp.in"
                  "include/wsf_extensions.hpp")
endmacro()

# Supports linking of optional extensions when doing a build. This macro should
# be called from the CMakeLists.txt file that generates an executable.
macro(link_wsf_optional_projects TARGET)
   get_property(WSF_OPTIONAL_PROJECT_NAMES GLOBAL PROPERTY WSF_OPTIONAL_PROJECT_NAMES)
   get_property(WSF_OPTIONAL_PROJECT_DEFINES GLOBAL PROPERTY WSF_OPTIONAL_PROJECT_DEFINES)
   get_property(WSF_OPTIONAL_PROJECT_TYPES GLOBAL PROPERTY WSF_OPTIONAL_PROJECT_TYPES)
   foreach(PROJNAME ${WSF_OPTIONAL_PROJECT_NAMES})
      set(FLAG 0)
      list(FIND WSF_OPTIONAL_PROJECT_NAMES ${PROJNAME} IDX)
      list(GET WSF_OPTIONAL_PROJECT_DEFINES ${IDX} DEF)
      list(GET WSF_OPTIONAL_PROJECT_TYPES ${IDX} PROJTYPE)
      IF(TARGET ${PROJNAME} AND NOT (PROJTYPE STREQUAL "plugin"))
         get_target_property(TARGETTYPE ${PROJNAME} TYPE)
         if(TARGETTYPE STREQUAL "STATIC_LIBRARY" OR TARGETTYPE STREQUAL "SHARED_LIBRARY")
            if(BUILD_WITH_${PROJNAME})
               target_link_libraries(${TARGET} ${PROJNAME})
               set(FLAG 1)
            endif(BUILD_WITH_${PROJNAME})
         endif()
         #append_target_properties(${TARGET} COMPILE_FLAGS "-D${DEF}=${FLAG}")
      ENDIF()
   endforeach(PROJNAME ${WSF_OPTIONAL_PROJECT_NAMES})
endmacro()

# For a given application, find auto test directories in optional extensions and add them to a list
# Input:
# TARGET: the application for which we are seeking tests
# Output:
# TESTDIRS: A list of directories containing tests for TARGET
# TESTNAMES: A list of names of projects which have tests for TARGET
function(get_optional_project_tests TARGET)
   unset(TESTNAMES)
   unset(TESTDIRS)

   get_property(WSF_OPTIONAL_PROJECT_NAMES GLOBAL PROPERTY WSF_OPTIONAL_PROJECT_NAMES)
   get_property(WSF_OPTIONAL_PROJECT_EXTDIRS GLOBAL PROPERTY WSF_OPTIONAL_PROJECT_EXTDIRS)

   foreach(PROJNAME ${WSF_OPTIONAL_PROJECT_NAMES})
      list(FIND WSF_OPTIONAL_PROJECT_NAMES ${PROJNAME} IDX)
      list(GET WSF_OPTIONAL_PROJECT_EXTDIRS ${IDX} EXTDIR)
      if(EXISTS "${EXTDIR}/test_${TARGET}" AND IS_DIRECTORY "${EXTDIR}/test_${TARGET}")
         if(BUILD_WITH_${PROJNAME})
            list(APPEND TESTDIRS "${EXTDIR}/test_${TARGET}")
            list(APPEND TESTNAMES "${PROJNAME}")
         endif(BUILD_WITH_${PROJNAME})
      endif()
   endforeach(PROJNAME ${WSF_OPTIONAL_PROJECT_NAMES})
   # Save the list of extension test directories
   set(TESTNAMES ${TESTNAMES} PARENT_SCOPE)
   set(TESTDIRS ${TESTDIRS} PARENT_SCOPE)
endfunction()
